use rust_decimal::Decimal;
use serde::Serialize;

use crate::{error::SqlxErr, store::get_pool};

#[derive(Debug, Serialize)]
pub struct TbOrder {
    pub id: u64,
    device_id: u64,
    cargo_col: u8,
    cargo_row: u8,
    product_id: u64,
    create_timestamp: u64,
    amount: Decimal,
    pay_method: String,
}

pub async fn create(
    device_id: u64,
    cargo_col: u8,
    cargo_row: u8,
    product_id: u64,
    create_timestamp: u64,
    amount: Decimal,
    pay_method: &str,
) -> Result<u64, SqlxErr> {
    let ret = sqlx::query!(
        r#"
        INSERT INTO tb_order (
            device_id, cargo_col, cargo_row, product_id, create_timestamp, amount, pay_method
        ) VALUES (?, ?, ?, ?, ?, ?, ?)
    "#,
        device_id,
        cargo_col,
        cargo_row,
        product_id,
        create_timestamp,
        amount,
        pay_method
    )
    .execute(get_pool())
    .await?;

    Ok(ret.last_insert_id())
}

pub async fn query_with_device(
    device_id: u64,
    begin: u64,
    end: u64,
) -> Result<Box<[TbOrder]>, SqlxErr> {
    let orders = sqlx::query_as!(
        TbOrder,
        r#"SELECT id, device_id, cargo_col, cargo_row, product_id, create_timestamp, amount, pay_method 
        FROM tb_order 
        WHERE device_id = ? AND create_timestamp >= ? AND create_timestamp <= ?"#,
        device_id, begin, end
    ).fetch_all(get_pool()).await?;

    Ok(orders.into_boxed_slice())
}
